import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.Serializable;
import java.util.Random;

import javax.swing.*;

/**
 * Represents a M.U.L.E. map
 * 
 * @author Sherman Mathews && Megan Beebe
 */

public class Map implements Serializable {
	/*
	 * town is a Town Object
	 * totalPanel will be returned by generatePanel
	 * mapPanel is a JPanel representation of the Map
	 * pressedTownButton is a boolean that is true when the user clicks on the Town button
	 * map is an array of all the properties
	 * townRep is a JPanel representation of the Town
	 * currPropOwner is the owner of the current Property
	 */
	private Town town;
	private JPanel totalPanel;
	private JPanel mapPanel;
	private boolean pressedTownButton = false;
	private Property[] map = new Property[45];
	private PicButton[] buttonArray = new PicButton[45];
	private JPanel townRep;
	//private int currentProperty;
	private Player currPropOwner;
	private int count = 0;
	private boolean random = false;

	/**
	 * Creates a new map object with a town
	 * 
	 * @param town the map's town
	 */
	public Map(Town town){
		this.setTown(town);
		map = standardMap();
		//this.setPropertyArr(propertyArr);
	}
	
	public void setRandom(boolean bool) {
		random = bool;
	}
	
	public void setMap(Property[] arr) {
		map = arr;
	}

	/**
	 * generates a map panel
	 * @return panel for the map
	 * @throws IOException 
	 */
	public JPanel generatePanel() throws IOException  {
		if (count == 0 && random == true)
			map = randomMap();
		totalPanel = new JPanel(new BorderLayout());
		mapPanel = new JPanel();
		mapPanel.setLayout(new GridLayout(5, 9));
		townRep = GameModel.getInstance().getMap().getTown().createTown();
		PicButton temp;
		for (int i = 0; i < 45; i++) {
			//temp is a JButton that is the current button to be added to the Map
			String type = map[i].getTerrainType();
			if (type.equalsIgnoreCase("Plain")){
				temp = new PicButton(getClass().getResource("Images/plain_PNG.png"));
			}
			else if (type.equalsIgnoreCase("Mountain One")) {
				temp = new PicButton(getClass().getResource("Images/mtn1_PNG.png"));
			}
			else if (type.equalsIgnoreCase("Mountain Two")) {
				temp = new PicButton(getClass().getResource("Images/mtn2_PNG.png"));
			}
			else if (type.equalsIgnoreCase("Mountain Three")) {
				temp = new PicButton(getClass().getResource("Images/mtn3_PNG.png"));
			}
			else if (type.equalsIgnoreCase("River")) {
				temp = new PicButton(getClass().getResource("Images/river_PNG.png"));
			}
			else {
				temp = new PicButton(getClass().getResource("Images/town_PNG.png"));
			}

			//currProp is the current Property that is being added to the Map
			final Property currProp = getProperty(i);
			//if owned, set color properly
			if (map[i].getOwner() != null) {
				String color = map[i].getOwner().colorToString();
				if (color.equalsIgnoreCase("Blue")) {
					if (type.equalsIgnoreCase("Plain")){
						
						if (map[i].hasMule() && map[i].getMule().getType() == 3)
							temp = new PicButton(getClass().getResource("MuleProps/plain_blue_food.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 4)
							temp = new PicButton(getClass().getResource("MuleProps/plain_blue_energy.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 5)
							temp = new PicButton(getClass().getResource("MuleProps/plain_blue_ore.png"));
						else
							temp = new PicButton(getClass().getResource("Images/plain_blue_PNG.png"));
					}
					
					else if (type.equalsIgnoreCase("Mountain One")) {
						
						if (map[i].hasMule() && map[i].getMule().getType() == 3)
							temp = new PicButton(getClass().getResource("MuleProps/mtn1_blue_food.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 4)
							temp = new PicButton(getClass().getResource("MuleProps/mtn1_blue_energy.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 5)
							temp = new PicButton(getClass().getResource("MuleProps/mtn1_blue_ore.png"));
						else
							temp = new PicButton(getClass().getResource("Images/mtn1_blue_PNG.png"));
					}
					
					else if (type.equalsIgnoreCase("Mountain Two")) {

						if (map[i].hasMule() && map[i].getMule().getType() == 3)
							temp = new PicButton(getClass().getResource("MuleProps/mtn2_blue_food.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 4)
							temp = new PicButton(getClass().getResource("MuleProps/mtn2_blue_energy.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 5)
							temp = new PicButton(getClass().getResource("MuleProps/mtn2_blue_ore.png"));
						else
							temp = new PicButton(getClass().getResource("Images/mtn2_blue_PNG.png"));
					}
					
					else if (type.equalsIgnoreCase("Mountain Three")) {

						if (map[i].hasMule() && map[i].getMule().getType() == 3)
							temp = new PicButton(getClass().getResource("MuleProps/mtn3_blue_food.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 4)
							temp = new PicButton(getClass().getResource("MuleProps/mtn3_blue_energy.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 5)
							temp = new PicButton(getClass().getResource("MuleProps/mtn3_blue_ore.png"));
						else
							temp = new PicButton(getClass().getResource("Images/mtn3_blue_PNG.png"));
					}
					
					else {
						if (map[i].hasMule() && map[i].getMule().getType() == 3)
							temp = new PicButton(getClass().getResource("MuleProps/river_blue_food.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 4)
							temp = new PicButton(getClass().getResource("MuleProps/river_blue_energy.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 5)
							temp = new PicButton(getClass().getResource("MuleProps/river_blue_ore.png"));
						else
							temp = new PicButton(getClass().getResource("Images/river_blue_PNG.png"));
					}
				}
				else if (color.equalsIgnoreCase("Red")) {
					if (type.equalsIgnoreCase("Plain")) {
						if (map[i].hasMule() && map[i].getMule().getType() == 3)
							temp = new PicButton(getClass().getResource("MuleProps/plain_red_food.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 4)
							temp = new PicButton(getClass().getResource("MuleProps/plain_red_energy.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 5)
							temp = new PicButton(getClass().getResource("MuleProps/plain_red_ore.png"));
						else
							temp = new PicButton(getClass().getResource("Images/plain_red_PNG.png"));
					}
					
					else if (type.equalsIgnoreCase("Mountain One")) {
						if (map[i].hasMule() && map[i].getMule().getType() == 3)
							temp = new PicButton(getClass().getResource("MuleProps/mtn1_red_food.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 4)
							temp = new PicButton(getClass().getResource("MuleProps/mtn1_red_energy.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 5)
							temp = new PicButton(getClass().getResource("MuleProps/mtn1_red_ore.png"));
						else
							temp = new PicButton(getClass().getResource("Images/mtn1_red_PNG.png"));
					}
					
					else if (type.equalsIgnoreCase("Mountain Two")) {
							if (map[i].hasMule() && map[i].getMule().getType() == 3)
								temp = new PicButton(getClass().getResource("MuleProps/mtn2_red_food.png"));
							else if (map[i].hasMule() && map[i].getMule().getType() == 4)
								temp = new PicButton(getClass().getResource("MuleProps/mtn2_red_energy.png"));
							else if (map[i].hasMule() && map[i].getMule().getType() == 5)
								temp = new PicButton(getClass().getResource("MuleProps/mtn2_red_ore.png"));
							else
								temp = new PicButton(getClass().getResource("Images/mtn2_red_PNG.png"));
						}
					else if (type.equalsIgnoreCase("Mountain Three")) {
							if (map[i].hasMule() && map[i].getMule().getType() == 3)
								temp = new PicButton(getClass().getResource("MuleProps/mtn3_red_food.png"));
							else if (map[i].hasMule() && map[i].getMule().getType() == 4)
								temp = new PicButton(getClass().getResource("MuleProps/mtn3_red_energy.png"));
							else if (map[i].hasMule() && map[i].getMule().getType() == 5)
								temp = new PicButton(getClass().getResource("MuleProps/mtn3_red_ore.png"));
							else
								temp = new PicButton(getClass().getResource("Images/mtn3_red_PNG.png"));
						}
					else {
							if (map[i].hasMule() && map[i].getMule().getType() == 3)
								temp = new PicButton(getClass().getResource("MuleProps/river_red_food.png"));
							else if (map[i].hasMule() && map[i].getMule().getType() == 4)
								temp = new PicButton(getClass().getResource("MuleProps/river_red_energy.png"));
							else if (map[i].hasMule() && map[i].getMule().getType() == 5)
								temp = new PicButton(getClass().getResource("MuleProps/river_red_ore.png"));
							else
								temp = new PicButton(getClass().getResource("Images/river_red_PNG.png"));
						}
				}
				else if (color.equalsIgnoreCase("Yellow")) {
					if (type.equalsIgnoreCase("Plain")) {
						if (map[i].hasMule() && map[i].getMule().getType() == 3)
							temp = new PicButton(getClass().getResource("MuleProps/plain_yellow_food.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 4)
							temp = new PicButton(getClass().getResource("MuleProps/plain_yellow_energy.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 5)
							temp = new PicButton(getClass().getResource("MuleProps/plain_yellow_ore.png"));
						else
							temp = new PicButton(getClass().getResource("Images/plain_yellow_PNG.png"));
					}
					else if (type.equalsIgnoreCase("Mountain One")) {
						if (map[i].hasMule() && map[i].getMule().getType() == 3)
							temp = new PicButton(getClass().getResource("MuleProps/mtn1_yellow_food.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 4)
							temp = new PicButton(getClass().getResource("MuleProps/mtn1_yellow_energy.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 5)
							temp = new PicButton(getClass().getResource("MuleProps/mtn1_yellow_ore.png"));
						else
							temp = new PicButton(getClass().getResource("Images/mtn1_yellow_PNG.png"));
					}
					else if (type.equalsIgnoreCase("Mountain Two")) {
						if (map[i].hasMule() && map[i].getMule().getType() == 3)
							temp = new PicButton(getClass().getResource("MuleProps/mtn2_yellow_food.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 4)
							temp = new PicButton(getClass().getResource("MuleProps/mtn2_yellow_energy.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 5)
							temp = new PicButton(getClass().getResource("MuleProps/mtn2_yellow_ore.png"));
						else
							temp = new PicButton(getClass().getResource("Images/mtn2_yellow_PNG.png"));
					}
					else if (type.equalsIgnoreCase("Mountain Three")) {
						if (map[i].hasMule() && map[i].getMule().getType() == 3)
							temp = new PicButton(getClass().getResource("MuleProps/mtn3_yellow_food.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 4)
							temp = new PicButton(getClass().getResource("MuleProps/mtn3_yellow_energy.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 5)
							temp = new PicButton(getClass().getResource("MuleProps/mtn3_yellow_ore.png"));
						else
							temp = new PicButton(getClass().getResource("Images/mtn3_yellow_PNG.png"));
					}
					else {
						if (map[i].hasMule() && map[i].getMule().getType() == 3)
							temp = new PicButton(getClass().getResource("MuleProps/river_yellow_food.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 4)
							temp = new PicButton(getClass().getResource("MuleProps/river_yellow_energy.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 5)
							temp = new PicButton(getClass().getResource("MuleProps/river_yellow_ore.png"));
						else
							temp = new PicButton(getClass().getResource("Images/river_yellow_PNG.png"));
					}
				}
				else if (color.equalsIgnoreCase("Purple")) {
					if (type.equalsIgnoreCase("Plain")){
						if (map[i].hasMule() && map[i].getMule().getType() == 3)
							temp = new PicButton(getClass().getResource("MuleProps/plain_purple_food.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 4)
							temp = new PicButton(getClass().getResource("MuleProps/plain_purple_energy.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 5)
							temp = new PicButton(getClass().getResource("MuleProps/plain_purple_ore.png"));
						else
							temp = new PicButton(getClass().getResource("Images/plain_purple_PNG.png"));
					}
					else if (type.equalsIgnoreCase("Mountain One")) {
						if (map[i].hasMule() && map[i].getMule().getType() == 3)
							temp = new PicButton(getClass().getResource("MuleProps/mtn1_purple_food.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 4)
							temp = new PicButton(getClass().getResource("MuleProps/mtn1_purple_energy.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 5)
							temp = new PicButton(getClass().getResource("MuleProps/mtn1_purple_ore.png"));
						else
							temp = new PicButton(getClass().getResource("Images/mtn1_purple_PNG.png"));
					}
					else if (type.equalsIgnoreCase("Mountain Two")) {
						if (map[i].hasMule() && map[i].getMule().getType() == 3)
							temp = new PicButton(getClass().getResource("MuleProps/mtn2_purple_food.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 4)
							temp = new PicButton(getClass().getResource("MuleProps/mtn2_purple_energy.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 5)
							temp = new PicButton(getClass().getResource("MuleProps/mtn2_purple_ore.png"));
						else
							temp = new PicButton(getClass().getResource("Images/mtn2_purple_PNG.png"));
					}
					else if (type.equalsIgnoreCase("Mountain Three")) {
						if (map[i].hasMule() && map[i].getMule().getType() == 3)
							temp = new PicButton(getClass().getResource("MuleProps/mtn3_purple_food.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 4)
							temp = new PicButton(getClass().getResource("MuleProps/mtn3_purple_energy.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 5)
							temp = new PicButton(getClass().getResource("MuleProps/mtn3_purple_ore.png"));
						else
							temp = new PicButton(getClass().getResource("Images/mtn3_purple_PNG.png"));
					}
					else {
						if (map[i].hasMule() && map[i].getMule().getType() == 3)
							temp = new PicButton(getClass().getResource("MuleProps/river_purple_food.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 4)
							temp = new PicButton(getClass().getResource("MuleProps/river_purple_energy.png"));
						else if (map[i].hasMule() && map[i].getMule().getType() == 5)
							temp = new PicButton(getClass().getResource("MuleProps/river_purple_ore.png"));
						else
							temp = new PicButton(getClass().getResource("Images/river_purple_PNG.png"));
					}
				}
				else
				{
					temp = new PicButton(getClass().getResource("Images/town_PNG.png"));
					temp.addActionListener(new ActionListener()
					{
						public void actionPerformed(ActionEvent e){
							pressedTownButton = true;
							mapPanel.setVisible(false);
							totalPanel.add(townRep, BorderLayout.CENTER);
							townRep.setVisible(true);
							totalPanel.repaint();
						}
					});
					totalPanel.add(mapPanel, BorderLayout.CENTER);
				}        
				mapPanel.add(temp);
				if (map[i].getOwner() != null) {
					currPropOwner = map[i].getOwner();
					temp.addActionListener(new ActionListener() {
						public void actionPerformed(ActionEvent e) {
							//do something
						}
					});
				}
			}
			else if (map[i].getTerrainNum() == 1) 
			{
				temp.setBackground(GameModel.plainGreen);
				temp.addActionListener(new ActionListener()
				{
					public void actionPerformed(ActionEvent e)
					{	
					}
				});

			}

			else if (map[i].getTerrainNum() == 2 || 
					map[i].getTerrainNum() == 3 ||
					map[i].getTerrainNum() == 4)
			{
				temp.setBackground(GameModel.mountainBrown);
				temp.addActionListener(new ActionListener()
				{
					public void actionPerformed(ActionEvent e)
					{						
					}
				});
			}

			else if (map[i].getTerrainNum() == 5)
			{
				temp.setBackground(GameModel.riverBlue);
				temp.addActionListener(new ActionListener()
				{
					public void actionPerformed(ActionEvent e)
					{						
					}
				});
			}

			else
			{
				temp.setBackground(GameModel.townOrange);
				temp.addActionListener(new ActionListener()
				{
					public void actionPerformed(ActionEvent e)
					{
						pressedTownButton = true;
						mapPanel.setVisible(false);
						totalPanel.add(townRep, BorderLayout.CENTER);
						townRep.setVisible(true);
						totalPanel.repaint();
					}
				});
				totalPanel.add(mapPanel, BorderLayout.CENTER);
			}

			//temp.add(i + ": ", new JLabel((map[i]).getTerrainType()));
			mapPanel.add(temp);
			buttonArray[i] = temp;
		}
		count++;
		return totalPanel;
	}

	private boolean getRandom() {
		// TODO Auto-generated method stub
		return random;
	}

	/**
	 * generates a random map
	 * @return 
	 */
	public Property[] randomMap() {
		map[4] = new Property(5);
		map[13] = new Property(5);
		map[22] = new Property(6);
		map[31] = new Property(5);
		map[40] = new Property(5);
		//rand is a Random object 
		Random rand = new Random();
		for (int i = 0; i < 45; i++) {
			if (i != 4 && i != 13 && i != 22 && i != 31 && i != 40) {
				int index = rand.nextInt(4) + 1;
				map[i] = new Property(index);
			}
		}
		return map;
	}

	/**
	 * returns the property at a location i
	 * @param i the location
	 * @return Property the property at the location
	 */
	public Property get(int i) {
		return map[i];
	}

	/**
	 * generates the standard map
	 */
	public Property[] standardMap() {
		//Row One
		map[0] = new Property(1);
		map[1] = new Property(1);
		map[2] = new Property(2);
		map[3] = new Property(1);
		map[4] = new Property(5);
		map[5] = new Property(1);
		map[6] = new Property(4);
		map[7] = new Property(1);
		map[8] = new Property(1);
		//Row Two
		map[9] = new Property(1);
		map[10] = new Property(2);
		map[11] = new Property(1);
		map[12] = new Property(1);
		map[13] = new Property(5);
		map[14] = new Property(1);
		map[15] = new Property(1);
		map[16] = new Property(1);
		map[17] = new Property(4);
		//Row Three
		map[18] = new Property(4);
		map[19] = new Property(1);
		map[20] = new Property(1);
		map[21] = new Property(1);
		map[22] = new Property(6);
		map[23] = new Property(1);
		map[24] = new Property(1);
		map[25] = new Property(1);
		map[26] = new Property(2);
		//Row Four
		map[27] = new Property(1);
		map[28] = new Property(3);
		map[29] = new Property(1);
		map[30] = new Property(1);
		map[31] = new Property(5);
		map[32] = new Property(1);
		map[33] = new Property(3);
		map[34] = new Property(1);
		map[35] = new Property(1);
		//Row Five
		map[36] = new Property(1);
		map[37] = new Property(1);
		map[38] = new Property(3);
		map[39] = new Property(1);
		map[40] = new Property(5);
		map[41] = new Property(1);
		map[42] = new Property(1);
		map[43] = new Property(1);
		map[44] = new Property(3);

		return map;
	}

	/**
	 * gets the map's town
	 * @return map's town
	 */
	public Town getTown() {
		return town;
	}

	/**
	 * set the map's town
	 * @param town the map's town
	 */
	public void setTown(Town town) {
		this.town = town;
	}

	/*
	 * gets the value of the boolean pressedTownButton
	 * @return pressedTownButton
	 */
	public boolean getPressedTownButton()
	{
		return pressedTownButton;
	}

	public PicButton[] getButtonArr() {
		return buttonArray;
	}

	/**
	 * gets the property at a given index
	 * @param index location of property in map
	 * @return property at index
	 */
	public Property getProperty(int index){
		return map[index];
	}

}
